package nape.geom;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class AABB{
    public var zpp_inner:ZPP_AABB;
    public function new(?x:Float=0,?y:Float=0,?width:Float=0,?height:Float=0){
        if(({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
            ret;
            #else Math.isNaN(x);
            #end
        })||({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](y);
            ret;
            #else Math.isNaN(y);
            #end
        }))throw "Error: AABB position cannot be NaN";
        if(({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](width);
            ret;
            #else Math.isNaN(width);
            #end
        })||({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](height);
            ret;
            #else Math.isNaN(height);
            #end
        }))throw "Error: AABB dimensions cannot be NaN";
        zpp_inner=ZPP_AABB.get(x,y,x+width,y+height);
        zpp_inner.outer=this;
    }
    #if swc@:keep#end public inline function copy()return new AABB(x,y,width,height)#if flash9#if swc@:keep#end public static inline function fromRect(rect:flash.geom.Rectangle){
        if(rect==null)throw "Error: Cannot create AABB from null Rectangle";
        return new AABB(rect.x,rect.y,rect.width,rect.height);
    }
    #end public var min(flibget_min,flibset_min):Vec2;
    inline function flibget_min()return zpp_inner.get_min()inline function flibset_min(min:Vec2){
        if(zpp_inner.immutable)throw "Error: AABB is immutable";
        if(min==null)throw "Error: Cannot assign null to AABB::"+"min";
        if(({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
            ret;
            #else Math.isNaN(x);
            #end
        })||({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](y);
            ret;
            #else Math.isNaN(y);
            #end
        }))throw "Error: AABB::"+"min"+" components cannot be NaN";
        if("min"=="min"){
            if(min.x>max.x)throw "Error: Assignment would cause negative width";
            if(min.y>max.y)throw "Error: Assignment would cause negative height";
        }
        else{
            if(min.x<min.x)throw "Error: Assignment would cause negative width";
            if(min.y<min.y)throw "Error: Assignment would cause negative height";
        }
        return this.min.set(min);
    }
    public var max(flibget_max,flibset_max):Vec2;
    inline function flibget_max()return zpp_inner.get_max()inline function flibset_max(max:Vec2){
        if(zpp_inner.immutable)throw "Error: AABB is immutable";
        if(max==null)throw "Error: Cannot assign null to AABB::"+"max";
        if(({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
            ret;
            #else Math.isNaN(x);
            #end
        })||({
            #if flash9 var ret:Bool=untyped __global__["isNaN"](y);
            ret;
            #else Math.isNaN(y);
            #end
        }))throw "Error: AABB::"+"max"+" components cannot be NaN";
        if("max"=="min"){
            if(max.x>max.x)throw "Error: Assignment would cause negative width";
            if(max.y>max.y)throw "Error: Assignment would cause negative height";
        }
        else{
            if(max.x<min.x)throw "Error: Assignment would cause negative width";
            if(max.y<min.y)throw "Error: Assignment would cause negative height";
        }
        return this.max.set(max);
    }
    public var x(flibget_x,flibset_x):Float;
    inline function flibget_x(){
        zpp_inner.validate();
        return zpp_inner.minx;
    }
    inline function flibset_x(x:Float){
        if(zpp_inner.immutable)throw "Error: AABB is immutable";
        if(this.x!=x){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
                ret;
                #else Math.isNaN(x);
                #end
            }))throw "Error: AABB::"+"x"+" cannot be NaN";
            if(x>max.x)throw "Error: Assignment would cause negative "+("x"=="x"?"width":"height");
            zpp_inner.minx=x;
            zpp_inner.invalidate();
        }
        return x;
    }
    public var y(flibget_y,flibset_y):Float;
    inline function flibget_y(){
        zpp_inner.validate();
        return zpp_inner.miny;
    }
    inline function flibset_y(y:Float){
        if(zpp_inner.immutable)throw "Error: AABB is immutable";
        if(this.y!=y){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](y);
                ret;
                #else Math.isNaN(y);
                #end
            }))throw "Error: AABB::"+"y"+" cannot be NaN";
            if(y>max.y)throw "Error: Assignment would cause negative "+("y"=="x"?"width":"height");
            zpp_inner.miny=y;
            zpp_inner.invalidate();
        }
        return y;
    }
    public var width(flibget_width,flibset_width):Float;
    inline function flibget_width(){
        zpp_inner.validate();
        return zpp_inner.width();
    }
    inline function flibset_width(width:Float){
        if(zpp_inner.immutable)throw "Error: AABB is immutable";
        if(this.width!=width){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](width);
                ret;
                #else Math.isNaN(width);
                #end
            }))throw "Error: AABB::"+"width"+" cannot be NaN";
            if(width<0)throw "Error: AABB::"+"width"+" ("+width+") must be >= 0";
            zpp_inner.maxx=this.x+width;
            zpp_inner.invalidate();
        }
        return width;
    }
    public var height(flibget_height,flibset_height):Float;
    inline function flibget_height(){
        zpp_inner.validate();
        return zpp_inner.height();
    }
    inline function flibset_height(height:Float){
        if(zpp_inner.immutable)throw "Error: AABB is immutable";
        if(this.height!=height){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](height);
                ret;
                #else Math.isNaN(height);
                #end
            }))throw "Error: AABB::"+"height"+" cannot be NaN";
            if(height<0)throw "Error: AABB::"+"height"+" ("+height+") must be >= 0";
            zpp_inner.maxy=this.y+height;
            zpp_inner.invalidate();
        }
        return height;
    }
    @:keep public inline function toString(){
        zpp_inner.validate();
        return zpp_inner.toString();
    }
}
